% The code is based on the following paper:
%   Chen, T. Y., Lin, Y. L., and Tzeng, L. Y., forthcoming.
%   Estimating probability weighting functions through option pricing bounds. Review of Asset Pricing Studies.
%
% Copyright: Tzu-Ying Chen, Yo-Lan Lin, Larry Y. Tzeng
% Date: January 30, 2024

clear

%% Setting
BV_Target = {'UB'};  

%% Load Data
FileName = ['AllTradingDate19962021_Monthly.mat'];
load(FileName, ...
     'Target_AllDate');             
clear FileName

Date_Monthly = Target_AllDate;                                
clear Target_AllDate 

%% Optimal Risk Preferences under Rank-Dependent Expected Utility
NUM_PL = 10;  
OPT_PL = nan(size(Date_Monthly, 1), NUM_PL);                               
OPT_COND_PL = nan(size(Date_Monthly, 1), 4);                                
OPT_Type_PL = nan(size(Date_Monthly, 1), 1);                               
for d = 1:size(Date_Monthly, 1)
    Target_Date = Date_Monthly(d, 1);
    Target_TTM = Date_Monthly(d, 3);
    
    % Load Data
    FileName = ['Summary_DEV_' num2str(Target_Date)];
    load(FileName, ...
         'Record_OPT_IS', 'Record_OPT_COND_IS', ...
         'Record_OPT_S', 'Record_OPT_COND_S', ...   
         'Record_OPT_CC', 'Record_OPT_COND_CC', ...   
         'Record_OPT_CV', 'Record_OPT_COND_CV');
    clear FileName    
    
    Index_NUM_VIO = 2;                                                     
    Index_DEV = 4;    
    Record_OPT = [Record_OPT_IS; ...
                  Record_OPT_S; ...
                  Record_OPT_CC; ...
                  Record_OPT_CV];
    Record_OPT_COND = [Record_OPT_COND_IS; ...
                       Record_OPT_COND_S; ...
                       Record_OPT_COND_CC; ...
                       Record_OPT_COND_CV];
                   
    if size(Record_OPT, 1) > 0
        Index = find(Record_OPT_COND(:, Index_NUM_VIO)==0);
        if length(Index) > 0
            [~, Index_Min] = min(Record_OPT_COND(Index, Index_DEV));
            Index = Index(Index_Min);                                      
            clear Index_Min        
            
            % Optimal Type (1: Inverse-S Shaped)
            %              (2: S Shaped)
            %              (3: Globally Concave)
            %              (4: Globally Convex)            
            OPT_PL(d, :) = Record_OPT(Index, :);
            OPT_COND_PL(d, :) = Record_OPT_COND(Index, :);
            OPT_Type_PL(d, :) = 1 + fix(Index / 10);
        else
            [~, Index_Min] = min(Record_OPT_COND(:, Index_DEV));
            Index = Index_Min;                                             
            clear Index_Min        
            
            OPT_PL(d, :) = Record_OPT(Index, :);
            OPT_COND_PL(d, :) = Record_OPT_COND(Index, :);            
            OPT_Type_PL(d, :) = - 1;                                       
        end
        clear Index 
    else
        OPT_PL(d, :) = 1;
        OPT_COND_PL(d, Index_NUM_VIO) = 0;
        OPT_Type_PL(d, :) = 0;        
    end
    clear Record_OPT_IS Record_OPT_S Record_OPT_CC Record_OPT_CV               
    clear Record_OPT_COND_IS Record_OPT_COND_S Record_OPT_COND_CC Record_OPT_COND_CV    
    clear Record_OPT Record_OPT_COND
    clear Target_Date Target_TTM Index_NUM_VIO Index_DEV
end
clear NUM_PL 
clear d

%% Output
FileName = ['Summary_PL_OPT_AllPeriod_OP_UB'];
save(FileName, ...
     'OPT_PL', 'OPT_Type_PL', ...
     'OPT_COND_PL', ...
     'Date_Monthly')
clear FileName 
